package com.zjitc.service.imp;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.MessageProperties;
import com.zjitc.common.Gsonal;
import com.zjitc.common.ServerResponse;
import com.zjitc.common.redis.RedisCache;
import com.zjitc.dao.CategoryDao;
import com.zjitc.dao.CollectDao;
import com.zjitc.dao.ProductDao;
import com.zjitc.pojo.Collect;
import com.zjitc.pojo.History;
import com.zjitc.pojo.Product;
import com.zjitc.pojo.User;
import com.zjitc.service.ProductService;
import com.zjitc.utils.MyNumber;
import com.zjitc.utils.RedisAuto;
import com.zjitc.utils.Utils;
import com.zjitc.vo.PageModel;
import java.io.IOException;
import java.util.Date;
import java.util.concurrent.TimeoutException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Create By IntelliJ IDEA
 *
 * @author: myq
 * @create-Time: 2017/11/15  10:57
 */
@Service
public class ProductServiceImpl implements ProductService {

  @Autowired
  private ProductDao productDao;

  @Autowired
  private CategoryDao categoryDao;
  @Autowired
  private CollectDao collectDao;
  @Autowired
  private RedisCache redis;
  @Autowired
  private ConnectionFactory factory;

  /**
   * 交换机
   */
  private final String EXCHANGE_NAME = "Exchange_BigWork";
  private final String INVENTORY = "inventory";
  private static final String COLLECT = "collect";
  private final String HOTS = "Hots";
  private final String NEWS = "News";
  private final String PRODUCTS = "products";

  @Override
  public List<Product> findHots() {
    checkredis();
    List<Product> products = redis.hashListGetAll(HOTS, Product.class);
    if(products.size() > MyNumber.TEN.ordinal()) {
      return products.subList(0, 10);
    }
    return products;
  }

  @Override
  public List<Product> findNews() {
    checkredis();
    List<Product> products = redis.hashListGetAll(NEWS, Product.class);
    if(products.size() > MyNumber.TEN.ordinal()) {
      return products.subList(0, 10);
    }
    return products;
  }

  @Override
  public Product findbyid(String pid) {
    String tojson = redis.hashMapget(PRODUCTS, pid);
    Product product = Gsonal.fromJson(tojson, Product.class);
    return product;
  }

  @Override
  public PageModel findall(String cid, int pageid, int count) {
    checkredis();
    List<Product> productList = redis.hashListGetAll(PRODUCTS, Product.class);
    List<Product> products = new ArrayList<>();
    productList.forEach(product -> {
      if (cid.equals(product.getCid())) {
        products.add(product);
      }
    });
    PageModel info = new PageModel(products, count, pageid);
    return info;
  }

  @Override
  public PageModel<Product> findAllProduct(int pageid, int count) {
    checkredis();
    List<Product> products = redis.hashListGetAll(PRODUCTS, Product.class);

    PageModel pageModel = new PageModel(products, count, pageid);
    return pageModel;
  }

  @Override
  public List<Product> findall() {
    return productDao.findall();
  }


  @Override
  public ModelAndView displaymsg(HttpSession session, String pid) {
    checkredis();
    int temp = 0;
    User user = (User) session.getAttribute("user");
    ModelAndView mc = new ModelAndView("jsp/product_info");
    Product product = redis.hashgetObject(PRODUCTS, pid, Product.class);
    makeHistory(session, product);
    mc.addObject("collect", temp);
    mc.addObject("product", product);
    return mc;
  }

  @Override
  public PageModel fuzzysearch(String fuzzy, int count, int pageid) {
    List<Product> listGetAll = redis.hashListGetAll(PRODUCTS, Product.class);
    List results = new ArrayList();
    Pattern pattern = Pattern.compile(fuzzy, Pattern.CASE_INSENSITIVE);
    listGetAll.forEach(item -> {
      Matcher matcher = pattern.matcher(item.getName());
      if (matcher.find()) {
        results.add(item);
      }
    });
    return new PageModel(results, count, pageid);
  }

  @Override
  public int updateProduct(Product product) {
    int update = productDao.update(product);
    System.out.println("在service中的Product是" + product);
    Product findbypid = productDao.findbypid(product.getPid());
    System.out.println("在数据库中的Product是：" + findbypid);
    RedisAuto.productRedis(productDao, categoryDao, redis, PRODUCTS);
    return update;
  }

  @Override
  public int addproduct(Product product) {
    String pid = Utils.code();
    product.setFlag(0);
    product.setPid(pid);
    product.setDate(new Date());
    redis.hashset(PRODUCTS, product.getPid(), Gsonal.tojson(product));
    int i = productDao.addnewProduct(product);
    return i;
  }

  @Override
  public void deleteByPid(String pid) {
    redis.delHash(PRODUCTS, pid);
    productDao.deletebypid(pid);
  }

  @Override
  public int updateInventory(String pid, Integer count) {
    Product product = redis.hashgetObject(PRODUCTS, pid, Product.class);
    product.setInventory(count);
    redis.hashset(PRODUCTS, pid, Gsonal.tojson(product));
    return productDao.update(product);
  }

  @Override
  public ServerResponse updateCollect(String pid, User user) {
    checkcollect(user.getUid());
    Collect collect = redis.hashgetObject(COLLECT, pid, Collect.class);
    Boolean b = true;
    if(collect == null){
      b = false;
      collect = new Collect(user.getUid(),pid);
    }
    int temp = 0;
    try (
        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();
    ) {
      if (b == false) {
        redis.hashset(COLLECT,pid,Gsonal.tojson(collect));
        channel.basicPublish(EXCHANGE_NAME, "addcollect", MessageProperties.PERSISTENT_TEXT_PLAIN,
            Gsonal.tojson(collect).getBytes());
        temp = 1;
      } else {
        redis.delHash(COLLECT,pid);
        channel.basicPublish(EXCHANGE_NAME, "delCollect", MessageProperties.PERSISTENT_TEXT_PLAIN,
            Gsonal.tojson(collect).getBytes());
      }
    } catch (TimeoutException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
    return ServerResponse.createSuccess(temp);
  }

  private void checkcollect(String uid) {
    if(!redis.exists(COLLECT)) {
      RedisAuto.collectRedis(collectDao, redis, uid, COLLECT);
    }
  }


  private void makeHistory(HttpSession session, Product product) {
    Object o = session.getAttribute("history");
    History history = null;
    if (o == null) {
      history = new History();
      session.setAttribute("history", history);
    } else {
      history = (History) o;
    }
    history.add(product);
  }

  public  void checkredis() {
    if (!redis.exists(PRODUCTS)) {
      RedisAuto.productRedis(productDao, categoryDao, redis, PRODUCTS);
    }
    if (!redis.exists(HOTS)) {
      RedisAuto.hotsRedis(productDao, redis, HOTS);
    }
    if (!redis.exists(NEWS)) {
      RedisAuto.newsRedis(productDao, redis, NEWS);
    }
    RedisAuto.inventoryRedis(productDao, redis, INVENTORY);
  }


}
